package nl.avans.osgi.hgttg.mice;

import java.util.Dictionary;
import java.util.Hashtable;

import nl.avans.osgi.hgttg.answers.Answer;
import nl.avans.osgi.hgttg.answers.impl.AnswerImpl;
import nl.avans.osgi.hgttg.questions.Question;
import nl.avans.osgi.hgttg.questions.impl.QuestionImpl;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;

public class Mice implements BundleActivator, Runnable {

    private BundleContext context;
    private ServiceTracker questionTracker;
    private ServiceTracker answerTracker;
    private Thread thread;
    private boolean gotAnswer;
    
    public void start(BundleContext context) throws Exception {
        this.context = context;
        
        String filterString = 
            "(&(objectClass=" + Question.class.getName() + ")" +
                " (for=mice))";
        Filter filter = this.context.createFilter(filterString);
        questionTracker = new ServiceTracker(this.context, filter , null);
        questionTracker.open();
        
        filterString = 
            "(&(objectClass=" + Answer.class.getName() + ")" +
                " (for=mice))";
        filter = this.context.createFilter(filterString);
        answerTracker = new ServiceTracker(this.context, filter , null);
        answerTracker.open();
        
        thread = new Thread(this, "Mice");
        thread.start();
    }

    public void stop(BundleContext context) throws Exception {
        questionTracker.close();
        answerTracker.close();
        thread = null;
//        questionCnt = 0;
//        answerCnt = 0;
    }

    @Override
    public void run() {
        Thread current = Thread.currentThread();
        int questionCnt = 0;
        int answerCnt = 0;
        gotAnswer = false;
        int cCnt = 0;
        boolean buildingComputer = false;
        boolean computerFinisched = false;
        while (thread == current) {
            buildingComputer |= (questionCnt == 3 && answerCnt == 3);
            if (questionCnt <= 2) {
                createQuestion(context, questionCnt);
            } else if (buildingComputer  && !computerFinisched) {
                System.out.print(".");
                cCnt++;
                if (cCnt == 5) {
                    computerFinisched = true;
                    System.out.println("");
                    createQuestion(context, questionCnt);
                }
            } else if (computerFinisched && questionCnt <= 5) {
                if (questionCnt == 4) {
                    createQuestion(context, questionCnt);
                }
                if (questionCnt == 5) {
                    createQuestion(context, questionCnt++);
                }
            } else if (gotAnswer) {
                createQuestion(context, questionCnt);
            }
            
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {}

            questionCnt = processQuestions(questionCnt, answerCnt);
            answerCnt = processAnswers(answerCnt, questionCnt);
        }
    }

    private int processQuestions(int questionNr, int answerNr) {
        ServiceReference[] questionRefs = questionTracker.getServiceReferences();
        if (questionRefs != null && questionRefs.length > 0) {
            ServiceReference qRef = questionRefs[0];
            Question question = (Question) questionTracker.getService(qRef);
            System.out.println(question.getQuestion());

            createAnswer(context, answerNr);
            if (question.isFromMice()) {
                questionNr = Math.min(++questionNr, qArray.length);
            }
            questionTracker.remove(qRef);
        }
        return questionNr;
    }
    
    private int processAnswers(int answerNr, int questionNr) {
        ServiceReference[] answerRefs = answerTracker.getServiceReferences();
        if (answerRefs != null && answerRefs.length > 0) {
            ServiceReference aRef = answerRefs[0];
            Answer answer = (Answer) answerTracker.getService(aRef);
            System.out.println(answer.getAnswer());

            if (answer.isFromMice()) {
                answerNr = Math.min(++answerNr, aArray.length);
            } else if (answer.isFromComputer()) {
                gotAnswer = true;
            }

            answerTracker.remove(aRef);
        }
        return answerNr;
    }

    private void createQuestion(BundleContext cntxt, int questionNr) {
        if (questionNr >= qArray.length) {
            return;
        }
        String[] qData = qArray[questionNr];
        Dictionary<String, String> prop = new Hashtable<String, String>();
        prop.put("for", qData[0]);
        prop.put("from", qData[1]);
        Question question = new QuestionImpl(qData[1], qData[2]);
        cntxt.registerService(Question.class.getName(), question, prop);
    }

    private void createAnswer(BundleContext cntxt, int answerNr) {
        if (answerNr >= aArray.length) {
            return;
        }
        String[] aData = aArray[answerNr];
        Dictionary<String, String> prop = new Hashtable<String, String>();
        prop.put("for", aData[0]);
        prop.put("from", aData[1]);
        Answer answer = new AnswerImpl(aData[1], aData[2]);
        cntxt.registerService(Answer.class.getName(), answer, prop);
    }
    
    private static String[][] qArray = new String[][] {
        {"mice", "Frankie", "He Benjy what do you think shall we create a new supercomputer again?"},
        {"mice", "Benjy", "It has to be mutch better then Earth and Deep Thougth."},
        {"mice", "Benjy", "OK lets build that thing."},
        {"mice", "Benjy", "Finally Deeper Thougth is finnished"},
        {"mice", "Frankie", "Lets ask THE question again!!"},
        {"computer", "mice", "Whats the answer to the ultimate question of life, the universe, and everything."},
        {"mice", "Benjy", "... eh, ... who's gonna tell this to Eric?"}
    };
    
    private static String[][] aArray = new String[][] {
        {"mice", "Benjy", "Yes, I think we should."},
        {"mice", "Frankie", "Mutch better yes. Lets call it \"Deeper Thougth\" and ask the original question again."},
        {"mice", "Frankie", "I'm working already."},
        {"mice", "Frankie", "Took many many years"}
    };
}
